Load

# File generated in /perturbation_16s/analysis/analysis_summer2019/generate_phyloseq.rmd
psSubj <- readRDS("../../data/16S/phyloseq/perturb_physeq_participants_decontam_15Jul19.rds")
psSubj
phyloseq-class experiment-level object
otu_table()   OTU Table:         [ 2425 taxa and 4402 samples ]
sample_data() Sample Data:       [ 4402 samples by 40 sample variables ]
tax_table()   Taxonomy Table:    [ 2425 taxa by 12 taxonomic ranks ]
phy_tree()    Phylogenetic Tree: [ 2425 tips and 2424 internal nodes ]
# otu_table()   OTU Table:         [ 2425 taxa and 4402 samples ]
# sample_data() Sample Data:       [ 4402 samples by 40 sample variables ]
SMP <- data.frame(sample_data(psSubj))
SUBJ <- SMP %>% select(Subject, Age:BirthYear) %>% distinct()
levels <- unique(SMP$Interval)
cols_itv <- c("grey77", colorRampPalette(brewer.pal(9, "Set1"))(length(levels) - 1))
names(cols_itv) <- c("NoInterv", setdiff(levels, "NoInterv"))
SMP %>%
    select(Group, Subject) %>%
    distinct() %>%
    group_by(Group) %>%
    summarise(subject_count = n())
load("output/pairwise_dist_subj_16S.rda")
ls()
 [1] "abx_bray_to_baseline"      "abx_intv_cols"             "abx_jacc_to_baseline"      "abx_uniFrac_to_baseline"  
 [5] "bray_to_baseline"          "bray.df"                   "brayD.ihs"                 "cc_bray_to_baseline"      
 [9] "cc_intv_cols"              "cc_jacc_to_baseline"       "cc_uniFrac_to_baseline"    "cols_itv"                 
[13] "curdir"                    "datadir"                   "diet_bray_to_baseline"     "diet_intv_cols"           
[17] "diet_jacc_to_baseline"     "diet_uniFrac_to_baseline"  "intv_cols"                 "jacc_to_baseline"         
[21] "jacc.df"                   "jaccardD"                  "levels"                    "noItv_bray_to_baseline"   
[25] "noItv_jacc_to_baseline"    "noItv_uniFrac_to_baseline" "psSubj"                    "SMP"                      
[29] "SUBJ"                      "uniFrac_to_baseline"       "uniFrac.df"                "uniFracD.lst"             

Distance to baseline

Bray-Curtis distance

Mean shift from baseline samples [-7, 0] measured with Bray-Curtis distance.

abx_bray_to_baseline <- bray.df %>%
  filter(Abx_RelDay_1 >= -7 & Abx_RelDay_1 <= 0) %>%
  group_by(Subject, Group, Abx_RelDay_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(Abx_RelDay = Abx_RelDay_2) %>%
  left_join(SMP)

diet_bray_to_baseline <- bray.df %>%
  filter(Diet_RelDay_1 >= -7 & Diet_RelDay_1 <= 0) %>%
  group_by(Subject, Group, Diet_RelDay_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(Diet_RelDay = Diet_RelDay_2) %>%
  left_join(SMP)

cc_bray_to_baseline <- bray.df %>%
  filter(CC_RelDay_1 >= -7 & CC_RelDay_1 <= 0) %>%
  group_by(Subject, Group, CC_RelDay_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(CC_RelDay = CC_RelDay_2) %>%
  left_join(SMP)


noItv_bray_to_baseline <- bray.df %>%
  filter(Group == "NoIntv", DaysFromStart_1 >= 0, DaysFromStart_1 <= 10) %>%
  group_by(Subject, Group, DaysFromStart_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(DaysFromStart = DaysFromStart_2) %>%
  left_join(SMP) %>%
  mutate(Interval = as.character(Interval))

bray_to_baseline <- list(
  abx_bray_to_baseline %>% mutate(Interval = Abx_Interval, RelDay = Abx_RelDay) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline),
  diet_bray_to_baseline %>% mutate(Interval = Diet_Interval, RelDay = Diet_RelDay) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline),
  cc_bray_to_baseline %>% mutate(Interval = CC_Interval, RelDay = CC_RelDay) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline),
  noItv_bray_to_baseline %>% mutate(RelDay = DaysFromStart) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline)
)
names(bray_to_baseline) <- c("Abx", "Diet", "CC", "NoIntv")
bray_to_baseline <- plyr::ldply(bray_to_baseline, function(df) df, .id = "perturbation") %>%
  mutate(Interval = factor(Interval, levels = names(intv_cols)))

# dim(abx_bray_to_baseline)  
# dim(diet_bray_to_baseline) 
# dim(cc_bray_to_baseline) 
# dim(noItv_bray_to_baseline)
# head(abx_bray_to_baseline)  
# head(diet_bray_to_baseline)  
# head(cc_bray_to_baseline)  
# head(noItv_bray_to_baseline)  


save(list = c("brayD.ihs", "bray.df", "bray_to_baseline",
              "jaccardD", "jacc.df",
              "uniFracD.lst", "uniFrac.df"),
     file = "output/pairwise_dist_to_baseline_subj_16S.rda")
bray_to_baseline %>%
  ggplot(
    aes(x = RelDay, y = dist_to_baseline, 
        group = Subject, color = Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1.2) + 
  scale_color_manual(values = intv_cols) + 
  theme(legend.position = "bottom") + 
  facet_wrap(~ perturbation, scales = "free_x") +
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from  perturbation") +
  ylab("Bray-Curtis distance to baseline") 

bray_to_baseline %>%
  filter(perturbation != "NoIntv") %>%
  ggplot(
    aes(x = RelDay, y = dist_to_baseline, 
        group = Subject, color = Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1) + 
  scale_color_manual(values = intv_cols) + 
  theme(legend.position = "bottom") + 
  facet_wrap(~ perturbation, scales = "free_x", ncol = 3) +
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from  perturbation") +
  ylab("Bray-Curtis distance to baseline") 

bray_to_baseline %>%
  filter(perturbation != "NoIntv", RelDay <=30, RelDay >= -30) %>%
  ggplot(
    aes(x = RelDay, y = dist_to_baseline, 
        group = Subject, color = Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1) + 
  scale_color_manual(values = intv_cols) + 
  theme(legend.position = "bottom") + 
  facet_wrap(~ perturbation, ncol = 3) +
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from  perturbation") +
  ylab("Bray-Curtis distance to baseline") 

abx_bray_to_baseline %>%
  mutate(Abx_Interval = factor(Abx_Interval, level = names(abx_intv_cols))) %>%
  filter(Abx_RelDay >= -50) %>%
  ggplot(
    aes(x = Abx_RelDay, y = dist_to_baseline, 
        group = Subject, color = Abx_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1.2) + 
  scale_color_manual(values = abx_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from initial antibiotic dose") +
  ylab("Bray-Curtis distance to 7 pre-antibiotic samples") 

abx_bray_to_baseline %>%
  mutate(Abx_Interval = factor(Abx_Interval, level = names(abx_intv_cols))) %>%
  filter(Abx_RelDay <= 30, Abx_RelDay >= -30) %>%
  ggplot(
    aes(x = Abx_RelDay, y = dist_to_baseline, 
        group = Subject, color = Abx_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1.5) + 
  scale_color_manual(values = abx_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from initial antibiotic dose") +
  ylab("Bray-Curtis distance to 7 pre-antibiotic samples") +
  ylim(0.05, 0.85)

diet_bray_to_baseline %>%
  mutate(Diet_Interval = factor(Diet_Interval, level = names(diet_intv_cols))) %>%
  filter(Diet_RelDay <= 50) %>%
  ggplot(
    aes(x = Diet_RelDay, y = dist_to_baseline, 
        group = Subject, color = Diet_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = diet_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from diet initiation") +
  ylab("Bray-Curtis distance to 7 pre-diet samples") 

diet_bray_to_baseline %>%
  mutate(Diet_Interval = factor(Diet_Interval, level = names(diet_intv_cols))) %>%
  filter(Diet_RelDay <= 30, Diet_RelDay >= -30) %>%
  ggplot(
    aes(x = Diet_RelDay, y = dist_to_baseline, 
        group = Subject, color = Diet_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = diet_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from diet initiation") +
  ylab("Bray-Curtis distance to 7 pre-diet samples") +
  ylim(0.05, 0.85)

cc_bray_to_baseline %>%
  mutate(CC_Interval = factor(CC_Interval, level = names(cc_intv_cols))) %>%
  filter(CC_RelDay >= -50 , CC_RelDay <= 50) %>%
  ggplot(
    aes(x = CC_RelDay, y = dist_to_baseline, 
        group = Subject, color = CC_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = cc_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from colon cleanout") +
  ylab("Bray-Curtis distance to 7 pre-colon-cleanout samples")

cc_bray_to_baseline %>%
  mutate(CC_Interval = factor(CC_Interval, level = names(cc_intv_cols))) %>%
 filter(CC_RelDay >= -30 , CC_RelDay <= 30) %>%
  ggplot(
    aes(x = CC_RelDay, y = dist_to_baseline, 
        group = Subject, color = CC_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = cc_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from colon cleanout") +
  ylab("Bray-Curtis distance to 7 pre-colon-cleanout samples") +
  ylim(0.05, 0.85)

Jaccard distance

abx_jacc_to_baseline <- jacc.df %>%
  filter(Abx_RelDay_1 >= -7 & Abx_RelDay_1 <= 0) %>%
  group_by(Subject, Group, Abx_RelDay_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(Abx_RelDay = Abx_RelDay_2) %>%
  left_join(SMP)

diet_jacc_to_baseline <- jacc.df %>%
  filter(Diet_RelDay_1 >= -7 & Diet_RelDay_1 <= 0) %>%
  group_by(Subject, Group, Diet_RelDay_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(Diet_RelDay = Diet_RelDay_2) %>% 
  left_join(SMP)

cc_jacc_to_baseline <- jacc.df %>%
  filter(CC_RelDay_1 >= -7 & CC_RelDay_1 <= 0) %>%
  group_by(Subject, Group, CC_RelDay_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(CC_RelDay = CC_RelDay_2) %>%
  left_join(SMP)


noItv_jacc_to_baseline <- jacc.df %>%
  filter(Group == "NoIntv", DaysFromStart_1 >= 0, DaysFromStart_1 <= 10) %>%
  group_by(Subject, Group, DaysFromStart_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(DaysFromStart = DaysFromStart_2) %>%
  left_join(SMP) %>%
  mutate(Interval = as.character(Interval))

jacc_to_baseline <- list(
  abx_jacc_to_baseline %>% mutate(Interval = Abx_Interval, RelDay = Abx_RelDay) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline),
  diet_jacc_to_baseline %>% mutate(Interval = Diet_Interval, RelDay = Diet_RelDay) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline),
  cc_jacc_to_baseline %>% mutate(Interval = CC_Interval, RelDay = CC_RelDay) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline),
  noItv_jacc_to_baseline %>% mutate(RelDay = DaysFromStart) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline)
)
names(jacc_to_baseline) <- c("Abx", "Diet", "CC", "NoIntv")
jacc_to_baseline <- plyr::ldply(jacc_to_baseline, function(df) df, .id = "perturbation") %>%
  mutate(Interval = factor(Interval, levels = names(intv_cols)))

save(list = c("brayD.ihs", "bray.df", "bray_to_baseline",
              "jaccardD", "jacc.df", "jacc_to_baseline",
              "uniFracD.lst", "uniFrac.df"),
     file = "output/pairwise_dist_to_baseline_subj_16S.rda")
jacc_to_baseline %>%
  ggplot(
    aes(x = RelDay, y = dist_to_baseline, 
        group = Subject, color = Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1.2) + 
  scale_color_manual(values = intv_cols) + 
  theme(legend.position = "bottom") + 
  facet_wrap(~ perturbation, scales = "free_x") +
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from  perturbation") +
  ylab("Jaccard distance to baseline") 

jacc_to_baseline %>%
  filter(perturbation != "NoIntv") %>%
  ggplot(
    aes(x = RelDay, y = dist_to_baseline, 
        group = Subject, color = Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1) + 
  scale_color_manual(values = intv_cols) + 
  theme(legend.position = "bottom") + 
  facet_wrap(~ perturbation, scales = "free_x", ncol = 3) +
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from  perturbation") +
  ylab("Jaccard distance to baseline") 

jacc_to_baseline %>%
  filter(perturbation != "NoIntv", RelDay <=30, RelDay >= -30) %>%
  ggplot(
    aes(x = RelDay, y = dist_to_baseline, 
        group = Subject, color = Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1) + 
  scale_color_manual(values = intv_cols) + 
  theme(legend.position = "bottom") + 
  facet_wrap(~ perturbation, ncol = 3) +
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from  perturbation") +
  ylab("Jaccard distance to baseline") 

abx_jacc_to_baseline %>%
  mutate(Abx_Interval = factor(Abx_Interval, level = names(abx_intv_cols))) %>%
  filter(Abx_RelDay >= -50) %>%
  ggplot(
    aes(x = Abx_RelDay, y = dist_to_baseline, 
        group = Subject, color = Abx_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1.2) + 
  scale_color_manual(values = abx_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from initial antibiotic dose") +
  ylab("Jaccard distance to 7 pre-antibiotic samples")

abx_jacc_to_baseline %>%
  mutate(Abx_Interval = factor(Abx_Interval, level = names(abx_intv_cols))) %>%
  filter(Abx_RelDay <= 30, Abx_RelDay >= -30) %>%
  ggplot(
    aes(x = Abx_RelDay, y = dist_to_baseline, 
        group = Subject, color = Abx_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1.5) + 
  scale_color_manual(values = abx_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from initial antibiotic dose") +
  ylab("Jaccard distance to 7 pre-antibiotic samples") +
  ylim(0.1, 1.0)

diet_jacc_to_baseline %>%
  mutate(Diet_Interval = factor(Diet_Interval, level = names(diet_intv_cols))) %>%
  filter(Diet_RelDay <= 50) %>%
  ggplot(
    aes(x = Diet_RelDay, y = dist_to_baseline, 
        group = Subject, color = Diet_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = diet_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from diet initiation") +
  ylab("Jaccard distance to 7 pre-diet samples")

diet_jacc_to_baseline %>%
  mutate(Diet_Interval = factor(Diet_Interval, level = names(diet_intv_cols))) %>%
  filter(Diet_RelDay <= 30, Diet_RelDay >= -30) %>%
  ggplot(
    aes(x = Diet_RelDay, y = dist_to_baseline, 
        group = Subject, color = Diet_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = diet_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from diet initiation") +
  ylab("Jaccard distance to 7 pre-diet samples") +
  ylim(0.1, 1.0)

cc_jacc_to_baseline %>%
  mutate(CC_Interval = factor(CC_Interval, level = names(cc_intv_cols))) %>%
  filter(CC_RelDay >= -50 , CC_RelDay <= 50) %>%
  ggplot(
    aes(x = CC_RelDay, y = dist_to_baseline, 
        group = Subject, color = CC_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = cc_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from colon cleanout") +
  ylab("Jaccard distance to 7 pre-colon-cleanout samples")

cc_jacc_to_baseline %>%
  mutate(CC_Interval = factor(CC_Interval, level = names(cc_intv_cols))) %>%
 filter(CC_RelDay >= -30 , CC_RelDay <= 30) %>%
  ggplot(
    aes(x = CC_RelDay, y = dist_to_baseline, 
        group = Subject, color = CC_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = cc_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from colon cleanout") +
  ylab("Jaccard distance to 7 pre-colon-cleanout samples") +
  ylim(0.1, 1.0)

(Unweighted) UniFrac

abx_uniFrac_to_baseline <- uniFrac.df %>%
  filter(Abx_RelDay_1 >= -7 & Abx_RelDay_1 <= 0) %>%
  group_by(Subject, Group, Abx_RelDay_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(Abx_RelDay = Abx_RelDay_2) %>%
  left_join(SMP)

diet_uniFrac_to_baseline <- uniFrac.df %>%
  filter(Diet_RelDay_1 >= -7 & Diet_RelDay_1 <= 0) %>%
  group_by(Subject, Group, Diet_RelDay_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(Diet_RelDay = Diet_RelDay_2) %>% 
  left_join(SMP)

cc_uniFrac_to_baseline <- uniFrac.df %>%
  filter(CC_RelDay_1 >= -7 & CC_RelDay_1 <= 0) %>%
  group_by(Subject, Group, CC_RelDay_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(CC_RelDay = CC_RelDay_2) %>%
  left_join(SMP)


noItv_uniFrac_to_baseline <- uniFrac.df %>%
  filter(Group == "NoIntv", DaysFromStart_1 >= 0, DaysFromStart_1 <= 10) %>%
  group_by(Subject, Group, DaysFromStart_2) %>%
  summarize(dist_to_baseline = mean(dist)) %>%
  rename(DaysFromStart = DaysFromStart_2) %>%
  left_join(SMP) %>%
  mutate(Interval = as.character(Interval))

uniFrac_to_baseline <- list(
  abx_uniFrac_to_baseline %>% mutate(Interval = Abx_Interval, RelDay = Abx_RelDay) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline),
  diet_uniFrac_to_baseline %>% mutate(Interval = Diet_Interval, RelDay = Diet_RelDay) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline),
  cc_uniFrac_to_baseline %>% mutate(Interval = CC_Interval, RelDay = CC_RelDay) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline),
  noItv_uniFrac_to_baseline %>% mutate(RelDay = DaysFromStart) %>%
    select(Meas_ID, Subject, Group, Interval, RelDay, dist_to_baseline)
)
names(uniFrac_to_baseline) <- c("Abx", "Diet", "CC", "NoIntv")
uniFrac_to_baseline <- plyr::ldply(uniFrac_to_baseline, function(df) df, .id = "perturbation") %>%
  mutate(Interval = factor(Interval, levels = names(intv_cols)))

save(list = c("brayD.ihs", "bray.df", "bray_to_baseline",
              "jaccardD", "jacc.df", "jacc_to_baseline",
              "uniFracD.lst", "uniFrac.df", "uniFrac_to_baseline"),
     file = "output/pairwise_dist_to_baseline_subj_16S.rda")
uniFrac_to_baseline %>%
  ggplot(
    aes(x = RelDay, y = dist_to_baseline, 
        group = Subject, color = Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1.2) + 
  scale_color_manual(values = intv_cols) + 
  theme(legend.position = "bottom") + 
  facet_wrap(~ perturbation, scales = "free_x") +
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from  perturbation") +
  ylab("UniFrac distance to baseline") 

uniFrac_to_baseline %>%
  filter(perturbation != "NoIntv") %>%
  ggplot(
    aes(x = RelDay, y = dist_to_baseline, 
        group = Subject, color = Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1) + 
  scale_color_manual(values = intv_cols) + 
  theme(legend.position = "bottom") + 
  facet_wrap(~ perturbation, scales = "free_x", ncol = 3) +
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from  perturbation") +
  ylab("UniFrac distance to baseline") 

uniFrac_to_baseline %>%
  filter(perturbation != "NoIntv", RelDay <=30, RelDay >= -30) %>%
  ggplot(
    aes(x = RelDay, y = dist_to_baseline, 
        group = Subject, color = Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1) + 
  scale_color_manual(values = intv_cols) + 
  theme(legend.position = "bottom") + 
  facet_wrap(~ perturbation, ncol = 3) +
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from  perturbation") +
  ylab("UniFrac distance to baseline") 

abx_uniFrac_to_baseline %>%
  mutate(Abx_Interval = factor(Abx_Interval, level = names(abx_intv_cols))) %>%
  filter(Abx_RelDay >= -50) %>%
  ggplot(
    aes(x = Abx_RelDay, y = dist_to_baseline, 
        group = Subject, color = Abx_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1.2) + 
  scale_color_manual(values = abx_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from initial antibiotic dose") +
  ylab("UniFrac distance to 7 pre-antibiotic samples")

abx_uniFrac_to_baseline %>%
  mutate(Abx_Interval = factor(Abx_Interval, level = names(abx_intv_cols))) %>%
  filter(Abx_RelDay <= 30, Abx_RelDay >= -30) %>%
  ggplot(
    aes(x = Abx_RelDay, y = dist_to_baseline, 
        group = Subject, color = Abx_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.5, size = 1.5) + 
  scale_color_manual(values = abx_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from initial antibiotic dose") +
  ylab("UniFrac distance to 7 pre-antibiotic samples") +
  ylim(0.1, 1.0)

diet_uniFrac_to_baseline %>%
  mutate(Diet_Interval = factor(Diet_Interval, level = names(diet_intv_cols))) %>%
  filter(Diet_RelDay <= 50) %>%
  ggplot(
    aes(x = Diet_RelDay, y = dist_to_baseline, 
        group = Subject, color = Diet_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = diet_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from  diet initiation") +
  ylab("UniFrac distance to 7 pre-diet samples")

diet_uniFrac_to_baseline %>%
  mutate(Diet_Interval = factor(Diet_Interval, level = names(diet_intv_cols))) %>%
  filter(Diet_RelDay <= 30, Diet_RelDay >= -30) %>%
  ggplot(
    aes(x = Diet_RelDay, y = dist_to_baseline, 
        group = Subject, color = Diet_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = diet_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from diet initiation") +
  ylab("UniFrac distance to 7 pre-diet samples") +
  ylim(0.1, 1.0)

cc_uniFrac_to_baseline %>%
  mutate(CC_Interval = factor(CC_Interval, level = names(cc_intv_cols))) %>%
  filter(CC_RelDay >= -50 , CC_RelDay <= 50) %>%
  ggplot(
    aes(x = CC_RelDay, y = dist_to_baseline, 
        group = Subject, color = CC_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = cc_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from colon cleanout") +
  ylab("UniFrac distance to 7 pre-colon-cleanout samples")

cc_uniFrac_to_baseline %>%
  mutate(CC_Interval = factor(CC_Interval, level = names(cc_intv_cols))) %>%
 filter(CC_RelDay >= -30 , CC_RelDay <= 30) %>%
  ggplot(
    aes(x = CC_RelDay, y = dist_to_baseline, 
        group = Subject, color = CC_Interval)) +
  geom_line(aes(group = Subject), alpha = 0.7, lwd = 0.5) + 
  geom_point(alpha = 0.7, size = 1.2) + 
  scale_color_manual(values = cc_intv_cols) + 
  theme(legend.position = "bottom") + 
  guides(colour = guide_legend(override.aes = list(size=3))) +
  xlab("Days from colon cleanout") +
  ylab("UniFrac distance to 7 pre-colon-cleanout samples") +
  ylim(0.1, 1.0)

sessionInfo()
R version 3.5.1 (2018-07-02)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: CentOS Linux 7 (Core)

Matrix products: default
BLAS/LAPACK: /share/software/user/open/openblas/0.2.19/lib/libopenblasp-r0.2.19.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] decontam_1.2.1       rmarkdown_1.14       BiocStyle_2.10.0     forcats_0.4.0        stringr_1.4.0        dplyr_0.8.3         
 [7] purrr_0.3.2          readr_1.3.1          tidyr_0.8.3          tibble_2.1.3         ggplot2_3.2.0        tidyverse_1.2.1.9000
[13] RColorBrewer_1.1-2   phyloseq_1.26.1     

loaded via a namespace (and not attached):
 [1] nlme_3.1-140        fs_1.3.1            lubridate_1.7.4     httr_1.4.0          tools_3.5.1         backports_1.1.4    
 [7] R6_2.4.0            vegan_2.5-5         DBI_1.0.0           lazyeval_0.2.2      BiocGenerics_0.28.0 mgcv_1.8-28        
[13] colorspace_1.4-1    permute_0.9-5       ade4_1.7-13         withr_2.1.2         tidyselect_0.2.5    compiler_3.5.1     
[19] cli_1.1.0           rvest_0.3.4         Biobase_2.42.0      xml2_1.2.0          labeling_0.3        scales_1.0.0       
[25] digest_0.6.20       XVector_0.22.0      base64enc_0.1-3     pkgconfig_2.0.2     htmltools_0.3.6     dbplyr_1.4.2       
[31] highr_0.8           rlang_0.4.0         readxl_1.3.1        rstudioapi_0.10     generics_0.0.2      jsonlite_1.6       
[37] magrittr_1.5        biomformat_1.10.1   Matrix_1.2-17       Rcpp_1.0.1          munsell_0.5.0       S4Vectors_0.20.1   
[43] Rhdf5lib_1.4.3      ape_5.3             stringi_1.4.3       yaml_2.2.0          MASS_7.3-51.4       zlibbioc_1.28.0    
[49] rhdf5_2.26.2        plyr_1.8.4          grid_3.5.1          parallel_3.5.1      crayon_1.3.4        lattice_0.20-38    
[55] Biostrings_2.50.2   haven_2.1.1         splines_3.5.1       multtest_2.38.0     hms_0.5.0           zeallot_0.1.0      
[61] knitr_1.23          pillar_1.4.2        igraph_1.2.4.1      reshape2_1.4.3      codetools_0.2-16    stats4_3.5.1       
[67] reprex_0.3.0        glue_1.3.1          evaluate_0.14       data.table_1.12.2   BiocManager_1.30.4  modelr_0.1.4       
[73] vctrs_0.2.0         foreach_1.4.4       cellranger_1.1.0    gtable_0.3.0        assertthat_0.2.1    xfun_0.8           
[79] broom_0.5.2         survival_2.44-1.1   viridisLite_0.3.0   iterators_1.0.10    IRanges_2.16.0      cluster_2.1.0      
LS0tCnRpdGxlOiAiUmVzcG9uc2UgdG8gcGVydHVyYmF0aW9ucyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmxpYnJhcnkoInBoeWxvc2VxIikKbGlicmFyeSgiUkNvbG9yQnJld2VyIikKbGlicmFyeSgidGlkeXZlcnNlIikKZGF0YWRpciA8LSAiLi4vLi4vZGF0YS8iCmN1cmRpciA8LSBnZXR3ZCgpCnRoZW1lX3NldCh0aGVtZV9idygpKQp0aGVtZV91cGRhdGUodGV4dCA9IGVsZW1lbnRfdGV4dCgyMCkpCgphYnhfaW50dl9jb2xzIDwtIGMoIlByZUFieCIgPSAiZ3JleTYwIiwgIk1pZEFieCIgPSAiI0U0MUExQyIsIAogICAgICAgICAgICAgICAgICAgIlBvc3RBYngiID0gIiMwMEJGQzQiLCAiVW5wQWJ4IiA9ICJQdXJwbGUiKQoKZGlldF9pbnR2X2NvbHMgPC0gYygiUHJlRGlldCIgPSAiZ3JleTYwIiwgIk1pZERpZXQiID0gIiNGRDhEM0MiLCAiUG9zdERpZXQiID0gIiM0REFGNEEiKQpjY19pbnR2X2NvbHMgPC0gYygiUHJlQ0MiID0gImdyZXk2MCIsICJQb3N0Q0MiID0gIiM3QTAxNzciKSAjIiNBRTAxN0UiKQoKaW50dl9jb2xzIDwtIGMoYWJ4X2ludHZfY29scywgZGlldF9pbnR2X2NvbHMsIGNjX2ludHZfY29scywgIk5vSW50ZXJ2IiA9ICJncmV5NjAiKQpgYGAKCgoKIyBMb2FkIAoKYGBge3J9CiMgRmlsZSBnZW5lcmF0ZWQgaW4gL3BlcnR1cmJhdGlvbl8xNnMvYW5hbHlzaXMvYW5hbHlzaXNfc3VtbWVyMjAxOS9nZW5lcmF0ZV9waHlsb3NlcS5ybWQKcHNTdWJqIDwtIHJlYWRSRFMoIi4uLy4uL2RhdGEvMTZTL3BoeWxvc2VxL3BlcnR1cmJfcGh5c2VxX3BhcnRpY2lwYW50c19kZWNvbnRhbV8xNUp1bDE5LnJkcyIpCnBzU3ViagojIG90dV90YWJsZSgpICAgT1RVIFRhYmxlOiAgICAgICAgIFsgMjQyNSB0YXhhIGFuZCA0NDAyIHNhbXBsZXMgXQojIHNhbXBsZV9kYXRhKCkgU2FtcGxlIERhdGE6ICAgICAgIFsgNDQwMiBzYW1wbGVzIGJ5IDQwIHNhbXBsZSB2YXJpYWJsZXMgXQpTTVAgPC0gZGF0YS5mcmFtZShzYW1wbGVfZGF0YShwc1N1YmopKQpTVUJKIDwtIFNNUCAlPiUgc2VsZWN0KFN1YmplY3QsIEFnZTpCaXJ0aFllYXIpICU+JSBkaXN0aW5jdCgpCmBgYAoKYGBge3J9ClNNUCAlPiUKICAgIHNlbGVjdChHcm91cCwgU3ViamVjdCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgZ3JvdXBfYnkoR3JvdXApICU+JQogICAgc3VtbWFyaXNlKHN1YmplY3RfY291bnQgPSBuKCkpCmBgYAoKYGBge3J9CmxvYWQoIm91dHB1dC9wYWlyd2lzZV9kaXN0X3N1YmpfMTZTLnJkYSIpCmxzKCkKYGBgCgoKIyBEaXN0YW5jZSB0byBiYXNlbGluZQoKIyMgQnJheS1DdXJ0aXMgZGlzdGFuY2UKCk1lYW4gc2hpZnQgZnJvbSBiYXNlbGluZSBzYW1wbGVzIFstNywgMF0gbWVhc3VyZWQgd2l0aCBCcmF5LUN1cnRpcyBkaXN0YW5jZS4KCmBgYHtyLCBldmFsID0gRkFMU0V9CmFieF9icmF5X3RvX2Jhc2VsaW5lIDwtIGJyYXkuZGYgJT4lCiAgZmlsdGVyKEFieF9SZWxEYXlfMSA+PSAtNyAmIEFieF9SZWxEYXlfMSA8PSAwKSAlPiUKICBncm91cF9ieShTdWJqZWN0LCBHcm91cCwgQWJ4X1JlbERheV8yKSAlPiUKICBzdW1tYXJpemUoZGlzdF90b19iYXNlbGluZSA9IG1lYW4oZGlzdCkpICU+JQogIHJlbmFtZShBYnhfUmVsRGF5ID0gQWJ4X1JlbERheV8yKSAlPiUKICBsZWZ0X2pvaW4oU01QKQoKZGlldF9icmF5X3RvX2Jhc2VsaW5lIDwtIGJyYXkuZGYgJT4lCiAgZmlsdGVyKERpZXRfUmVsRGF5XzEgPj0gLTcgJiBEaWV0X1JlbERheV8xIDw9IDApICU+JQogIGdyb3VwX2J5KFN1YmplY3QsIEdyb3VwLCBEaWV0X1JlbERheV8yKSAlPiUKICBzdW1tYXJpemUoZGlzdF90b19iYXNlbGluZSA9IG1lYW4oZGlzdCkpICU+JQogIHJlbmFtZShEaWV0X1JlbERheSA9IERpZXRfUmVsRGF5XzIpICU+JQogIGxlZnRfam9pbihTTVApCgpjY19icmF5X3RvX2Jhc2VsaW5lIDwtIGJyYXkuZGYgJT4lCiAgZmlsdGVyKENDX1JlbERheV8xID49IC03ICYgQ0NfUmVsRGF5XzEgPD0gMCkgJT4lCiAgZ3JvdXBfYnkoU3ViamVjdCwgR3JvdXAsIENDX1JlbERheV8yKSAlPiUKICBzdW1tYXJpemUoZGlzdF90b19iYXNlbGluZSA9IG1lYW4oZGlzdCkpICU+JQogIHJlbmFtZShDQ19SZWxEYXkgPSBDQ19SZWxEYXlfMikgJT4lCiAgbGVmdF9qb2luKFNNUCkKCgpub0l0dl9icmF5X3RvX2Jhc2VsaW5lIDwtIGJyYXkuZGYgJT4lCiAgZmlsdGVyKEdyb3VwID09ICJOb0ludHYiLCBEYXlzRnJvbVN0YXJ0XzEgPj0gMCwgRGF5c0Zyb21TdGFydF8xIDw9IDEwKSAlPiUKICBncm91cF9ieShTdWJqZWN0LCBHcm91cCwgRGF5c0Zyb21TdGFydF8yKSAlPiUKICBzdW1tYXJpemUoZGlzdF90b19iYXNlbGluZSA9IG1lYW4oZGlzdCkpICU+JQogIHJlbmFtZShEYXlzRnJvbVN0YXJ0ID0gRGF5c0Zyb21TdGFydF8yKSAlPiUKICBsZWZ0X2pvaW4oU01QKSAlPiUKICBtdXRhdGUoSW50ZXJ2YWwgPSBhcy5jaGFyYWN0ZXIoSW50ZXJ2YWwpKQoKYnJheV90b19iYXNlbGluZSA8LSBsaXN0KAogIGFieF9icmF5X3RvX2Jhc2VsaW5lICU+JSBtdXRhdGUoSW50ZXJ2YWwgPSBBYnhfSW50ZXJ2YWwsIFJlbERheSA9IEFieF9SZWxEYXkpICU+JQogICAgc2VsZWN0KE1lYXNfSUQsIFN1YmplY3QsIEdyb3VwLCBJbnRlcnZhbCwgUmVsRGF5LCBkaXN0X3RvX2Jhc2VsaW5lKSwKICBkaWV0X2JyYXlfdG9fYmFzZWxpbmUgJT4lIG11dGF0ZShJbnRlcnZhbCA9IERpZXRfSW50ZXJ2YWwsIFJlbERheSA9IERpZXRfUmVsRGF5KSAlPiUKICAgIHNlbGVjdChNZWFzX0lELCBTdWJqZWN0LCBHcm91cCwgSW50ZXJ2YWwsIFJlbERheSwgZGlzdF90b19iYXNlbGluZSksCiAgY2NfYnJheV90b19iYXNlbGluZSAlPiUgbXV0YXRlKEludGVydmFsID0gQ0NfSW50ZXJ2YWwsIFJlbERheSA9IENDX1JlbERheSkgJT4lCiAgICBzZWxlY3QoTWVhc19JRCwgU3ViamVjdCwgR3JvdXAsIEludGVydmFsLCBSZWxEYXksIGRpc3RfdG9fYmFzZWxpbmUpLAogIG5vSXR2X2JyYXlfdG9fYmFzZWxpbmUgJT4lIG11dGF0ZShSZWxEYXkgPSBEYXlzRnJvbVN0YXJ0KSAlPiUKICAgIHNlbGVjdChNZWFzX0lELCBTdWJqZWN0LCBHcm91cCwgSW50ZXJ2YWwsIFJlbERheSwgZGlzdF90b19iYXNlbGluZSkKKQpuYW1lcyhicmF5X3RvX2Jhc2VsaW5lKSA8LSBjKCJBYngiLCAiRGlldCIsICJDQyIsICJOb0ludHYiKQpicmF5X3RvX2Jhc2VsaW5lIDwtIHBseXI6OmxkcGx5KGJyYXlfdG9fYmFzZWxpbmUsIGZ1bmN0aW9uKGRmKSBkZiwgLmlkID0gInBlcnR1cmJhdGlvbiIpICU+JQogIG11dGF0ZShJbnRlcnZhbCA9IGZhY3RvcihJbnRlcnZhbCwgbGV2ZWxzID0gbmFtZXMoaW50dl9jb2xzKSkpCgojIGRpbShhYnhfYnJheV90b19iYXNlbGluZSkgIAojIGRpbShkaWV0X2JyYXlfdG9fYmFzZWxpbmUpIAojIGRpbShjY19icmF5X3RvX2Jhc2VsaW5lKSAKIyBkaW0obm9JdHZfYnJheV90b19iYXNlbGluZSkKIyBoZWFkKGFieF9icmF5X3RvX2Jhc2VsaW5lKSAgCiMgaGVhZChkaWV0X2JyYXlfdG9fYmFzZWxpbmUpICAKIyBoZWFkKGNjX2JyYXlfdG9fYmFzZWxpbmUpICAKIyBoZWFkKG5vSXR2X2JyYXlfdG9fYmFzZWxpbmUpICAKCgpzYXZlKGxpc3QgPSBjKCJicmF5RC5paHMiLCAiYnJheS5kZiIsICJicmF5X3RvX2Jhc2VsaW5lIiwKICAgICAgICAgICAgICAiamFjY2FyZEQiLCAiamFjYy5kZiIsCiAgICAgICAgICAgICAgInVuaUZyYWNELmxzdCIsICJ1bmlGcmFjLmRmIiksCiAgICAgZmlsZSA9ICJvdXRwdXQvcGFpcndpc2VfZGlzdF90b19iYXNlbGluZV9zdWJqXzE2Uy5yZGEiKQoKYGBgCgoKYGBge3IgYnJheS10by1iYXNlbGluZSwgZmlnLndpZHRoPTh9CmJyYXlfdG9fYmFzZWxpbmUgJT4lCiAgZ2dwbG90KAogICAgYWVzKHggPSBSZWxEYXksIHkgPSBkaXN0X3RvX2Jhc2VsaW5lLCAKICAgICAgICBncm91cCA9IFN1YmplY3QsIGNvbG9yID0gSW50ZXJ2YWwpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFN1YmplY3QpLCBhbHBoYSA9IDAuNywgbHdkID0gMC41KSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUsIHNpemUgPSAxLjIpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGludHZfY29scykgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKyAKICBmYWNldF93cmFwKH4gcGVydHVyYmF0aW9uLCBzY2FsZXMgPSAiZnJlZV94IikgKwogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTMpKSkgKwogIHhsYWIoIkRheXMgZnJvbSAgcGVydHVyYmF0aW9uIikgKwogIHlsYWIoIkJyYXktQ3VydGlzIGRpc3RhbmNlIHRvIGJhc2VsaW5lIikgCgpgYGAKCmBgYHtyIGJyYXktdG8tYmFzZWxpbmUtcGVydHVyYiwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9CmJyYXlfdG9fYmFzZWxpbmUgJT4lCiAgZmlsdGVyKHBlcnR1cmJhdGlvbiAhPSAiTm9JbnR2IikgJT4lCiAgZ2dwbG90KAogICAgYWVzKHggPSBSZWxEYXksIHkgPSBkaXN0X3RvX2Jhc2VsaW5lLCAKICAgICAgICBncm91cCA9IFN1YmplY3QsIGNvbG9yID0gSW50ZXJ2YWwpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFN1YmplY3QpLCBhbHBoYSA9IDAuNywgbHdkID0gMC41KSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUsIHNpemUgPSAxKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBpbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZmFjZXRfd3JhcCh+IHBlcnR1cmJhdGlvbiwgc2NhbGVzID0gImZyZWVfeCIsIG5jb2wgPSAzKSArCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tICBwZXJ0dXJiYXRpb24iKSArCiAgeWxhYigiQnJheS1DdXJ0aXMgZGlzdGFuY2UgdG8gYmFzZWxpbmUiKSAKCmBgYAoKYGBge3IgYnJheS10by1iYXNlbGluZS1wZXJ0dXJiLXpvb20sIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD00fQpicmF5X3RvX2Jhc2VsaW5lICU+JQogIGZpbHRlcihwZXJ0dXJiYXRpb24gIT0gIk5vSW50diIsIFJlbERheSA8PTMwLCBSZWxEYXkgPj0gLTMwKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoeCA9IFJlbERheSwgeSA9IGRpc3RfdG9fYmFzZWxpbmUsIAogICAgICAgIGdyb3VwID0gU3ViamVjdCwgY29sb3IgPSBJbnRlcnZhbCkpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU3ViamVjdCksIGFscGhhID0gMC43LCBsd2QgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSwgc2l6ZSA9IDEpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGludHZfY29scykgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKyAKICBmYWNldF93cmFwKH4gcGVydHVyYmF0aW9uLCBuY29sID0gMykgKwogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTMpKSkgKwogIHhsYWIoIkRheXMgZnJvbSAgcGVydHVyYmF0aW9uIikgKwogIHlsYWIoIkJyYXktQ3VydGlzIGRpc3RhbmNlIHRvIGJhc2VsaW5lIikgCgpgYGAKCmBgYHtyIGFieC1icmF5LXRvLWJhc2VsaW5lLCBmaWcud2lkdGg9OH0KYWJ4X2JyYXlfdG9fYmFzZWxpbmUgJT4lCiAgbXV0YXRlKEFieF9JbnRlcnZhbCA9IGZhY3RvcihBYnhfSW50ZXJ2YWwsIGxldmVsID0gbmFtZXMoYWJ4X2ludHZfY29scykpKSAlPiUKICBmaWx0ZXIoQWJ4X1JlbERheSA+PSAtNTApICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gQWJ4X1JlbERheSwgeSA9IGRpc3RfdG9fYmFzZWxpbmUsIAogICAgICAgIGdyb3VwID0gU3ViamVjdCwgY29sb3IgPSBBYnhfSW50ZXJ2YWwpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFN1YmplY3QpLCBhbHBoYSA9IDAuNywgbHdkID0gMC41KSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUsIHNpemUgPSAxLjIpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGFieF9pbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tIGluaXRpYWwgYW50aWJpb3RpYyBkb3NlIikgKwogIHlsYWIoIkJyYXktQ3VydGlzIGRpc3RhbmNlIHRvIDcgcHJlLWFudGliaW90aWMgc2FtcGxlcyIpIApgYGAKCgpgYGB7ciBhYngtYnJheS10by1iYXNlbGluZS16b29tLCBmaWcud2lkdGg9OH0KYWJ4X2JyYXlfdG9fYmFzZWxpbmUgJT4lCiAgbXV0YXRlKEFieF9JbnRlcnZhbCA9IGZhY3RvcihBYnhfSW50ZXJ2YWwsIGxldmVsID0gbmFtZXMoYWJ4X2ludHZfY29scykpKSAlPiUKICBmaWx0ZXIoQWJ4X1JlbERheSA8PSAzMCwgQWJ4X1JlbERheSA+PSAtMzApICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gQWJ4X1JlbERheSwgeSA9IGRpc3RfdG9fYmFzZWxpbmUsIAogICAgICAgIGdyb3VwID0gU3ViamVjdCwgY29sb3IgPSBBYnhfSW50ZXJ2YWwpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFN1YmplY3QpLCBhbHBoYSA9IDAuNywgbHdkID0gMC41KSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUsIHNpemUgPSAxLjUpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGFieF9pbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tIGluaXRpYWwgYW50aWJpb3RpYyBkb3NlIikgKwogIHlsYWIoIkJyYXktQ3VydGlzIGRpc3RhbmNlIHRvIDcgcHJlLWFudGliaW90aWMgc2FtcGxlcyIpICsKICB5bGltKDAuMDUsIDAuODUpCgpgYGAKCmBgYHtyIGRpZXQtYnJheS10by1iYXNlbGluZSwgZmlnLndpZHRoPTh9CgpkaWV0X2JyYXlfdG9fYmFzZWxpbmUgJT4lCiAgbXV0YXRlKERpZXRfSW50ZXJ2YWwgPSBmYWN0b3IoRGlldF9JbnRlcnZhbCwgbGV2ZWwgPSBuYW1lcyhkaWV0X2ludHZfY29scykpKSAlPiUKICBmaWx0ZXIoRGlldF9SZWxEYXkgPD0gNTApICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gRGlldF9SZWxEYXksIHkgPSBkaXN0X3RvX2Jhc2VsaW5lLCAKICAgICAgICBncm91cCA9IFN1YmplY3QsIGNvbG9yID0gRGlldF9JbnRlcnZhbCkpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU3ViamVjdCksIGFscGhhID0gMC43LCBsd2QgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgc2l6ZSA9IDEuMikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gZGlldF9pbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tIGRpZXQgaW5pdGlhdGlvbiIpICsKICB5bGFiKCJCcmF5LUN1cnRpcyBkaXN0YW5jZSB0byA3IHByZS1kaWV0IHNhbXBsZXMiKSAKCmBgYAoKCmBgYHtyIGRpZXQtYnJheS10by1iYXNlbGluZS16b29tLCBmaWcud2lkdGg9OH0KZGlldF9icmF5X3RvX2Jhc2VsaW5lICU+JQogIG11dGF0ZShEaWV0X0ludGVydmFsID0gZmFjdG9yKERpZXRfSW50ZXJ2YWwsIGxldmVsID0gbmFtZXMoZGlldF9pbnR2X2NvbHMpKSkgJT4lCiAgZmlsdGVyKERpZXRfUmVsRGF5IDw9IDMwLCBEaWV0X1JlbERheSA+PSAtMzApICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gRGlldF9SZWxEYXksIHkgPSBkaXN0X3RvX2Jhc2VsaW5lLCAKICAgICAgICBncm91cCA9IFN1YmplY3QsIGNvbG9yID0gRGlldF9JbnRlcnZhbCkpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU3ViamVjdCksIGFscGhhID0gMC43LCBsd2QgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgc2l6ZSA9IDEuMikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gZGlldF9pbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tIGRpZXQgaW5pdGlhdGlvbiIpICsKICB5bGFiKCJCcmF5LUN1cnRpcyBkaXN0YW5jZSB0byA3IHByZS1kaWV0IHNhbXBsZXMiKSArCiAgeWxpbSgwLjA1LCAwLjg1KQoKYGBgCgpgYGB7ciBjYy1icmF5LXRvLWJhc2VsaW5lLCBmaWcud2lkdGg9OH0KY2NfYnJheV90b19iYXNlbGluZSAlPiUKICBtdXRhdGUoQ0NfSW50ZXJ2YWwgPSBmYWN0b3IoQ0NfSW50ZXJ2YWwsIGxldmVsID0gbmFtZXMoY2NfaW50dl9jb2xzKSkpICU+JQogIGZpbHRlcihDQ19SZWxEYXkgPj0gLTUwICwgQ0NfUmVsRGF5IDw9IDUwKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoeCA9IENDX1JlbERheSwgeSA9IGRpc3RfdG9fYmFzZWxpbmUsIAogICAgICAgIGdyb3VwID0gU3ViamVjdCwgY29sb3IgPSBDQ19JbnRlcnZhbCkpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU3ViamVjdCksIGFscGhhID0gMC43LCBsd2QgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgc2l6ZSA9IDEuMikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY2NfaW50dl9jb2xzKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArIAogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTMpKSkgKwogIHhsYWIoIkRheXMgZnJvbSBjb2xvbiBjbGVhbm91dCIpICsKICB5bGFiKCJCcmF5LUN1cnRpcyBkaXN0YW5jZSB0byA3IHByZS1jb2xvbi1jbGVhbm91dCBzYW1wbGVzIikKCmBgYAoKYGBge3IgY2MtYnJheS10by1iYXNlbGluZS16b29tLCBmaWcud2lkdGg9OH0KY2NfYnJheV90b19iYXNlbGluZSAlPiUKICBtdXRhdGUoQ0NfSW50ZXJ2YWwgPSBmYWN0b3IoQ0NfSW50ZXJ2YWwsIGxldmVsID0gbmFtZXMoY2NfaW50dl9jb2xzKSkpICU+JQogZmlsdGVyKENDX1JlbERheSA+PSAtMzAgLCBDQ19SZWxEYXkgPD0gMzApICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gQ0NfUmVsRGF5LCB5ID0gZGlzdF90b19iYXNlbGluZSwgCiAgICAgICAgZ3JvdXAgPSBTdWJqZWN0LCBjb2xvciA9IENDX0ludGVydmFsKSkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBTdWJqZWN0KSwgYWxwaGEgPSAwLjcsIGx3ZCA9IDAuNSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC43LCBzaXplID0gMS4yKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjY19pbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tIGNvbG9uIGNsZWFub3V0IikgKwogIHlsYWIoIkJyYXktQ3VydGlzIGRpc3RhbmNlIHRvIDcgcHJlLWNvbG9uLWNsZWFub3V0IHNhbXBsZXMiKSArCiAgeWxpbSgwLjA1LCAwLjg1KQoKYGBgCgoKIyMgSmFjY2FyZCBkaXN0YW5jZQoKYGBge3IsIGV2YWwgPSBGQUxTRX0KYWJ4X2phY2NfdG9fYmFzZWxpbmUgPC0gamFjYy5kZiAlPiUKICBmaWx0ZXIoQWJ4X1JlbERheV8xID49IC03ICYgQWJ4X1JlbERheV8xIDw9IDApICU+JQogIGdyb3VwX2J5KFN1YmplY3QsIEdyb3VwLCBBYnhfUmVsRGF5XzIpICU+JQogIHN1bW1hcml6ZShkaXN0X3RvX2Jhc2VsaW5lID0gbWVhbihkaXN0KSkgJT4lCiAgcmVuYW1lKEFieF9SZWxEYXkgPSBBYnhfUmVsRGF5XzIpICU+JQogIGxlZnRfam9pbihTTVApCgpkaWV0X2phY2NfdG9fYmFzZWxpbmUgPC0gamFjYy5kZiAlPiUKICBmaWx0ZXIoRGlldF9SZWxEYXlfMSA+PSAtNyAmIERpZXRfUmVsRGF5XzEgPD0gMCkgJT4lCiAgZ3JvdXBfYnkoU3ViamVjdCwgR3JvdXAsIERpZXRfUmVsRGF5XzIpICU+JQogIHN1bW1hcml6ZShkaXN0X3RvX2Jhc2VsaW5lID0gbWVhbihkaXN0KSkgJT4lCiAgcmVuYW1lKERpZXRfUmVsRGF5ID0gRGlldF9SZWxEYXlfMikgJT4lIAogIGxlZnRfam9pbihTTVApCgpjY19qYWNjX3RvX2Jhc2VsaW5lIDwtIGphY2MuZGYgJT4lCiAgZmlsdGVyKENDX1JlbERheV8xID49IC03ICYgQ0NfUmVsRGF5XzEgPD0gMCkgJT4lCiAgZ3JvdXBfYnkoU3ViamVjdCwgR3JvdXAsIENDX1JlbERheV8yKSAlPiUKICBzdW1tYXJpemUoZGlzdF90b19iYXNlbGluZSA9IG1lYW4oZGlzdCkpICU+JQogIHJlbmFtZShDQ19SZWxEYXkgPSBDQ19SZWxEYXlfMikgJT4lCiAgbGVmdF9qb2luKFNNUCkKCgpub0l0dl9qYWNjX3RvX2Jhc2VsaW5lIDwtIGphY2MuZGYgJT4lCiAgZmlsdGVyKEdyb3VwID09ICJOb0ludHYiLCBEYXlzRnJvbVN0YXJ0XzEgPj0gMCwgRGF5c0Zyb21TdGFydF8xIDw9IDEwKSAlPiUKICBncm91cF9ieShTdWJqZWN0LCBHcm91cCwgRGF5c0Zyb21TdGFydF8yKSAlPiUKICBzdW1tYXJpemUoZGlzdF90b19iYXNlbGluZSA9IG1lYW4oZGlzdCkpICU+JQogIHJlbmFtZShEYXlzRnJvbVN0YXJ0ID0gRGF5c0Zyb21TdGFydF8yKSAlPiUKICBsZWZ0X2pvaW4oU01QKSAlPiUKICBtdXRhdGUoSW50ZXJ2YWwgPSBhcy5jaGFyYWN0ZXIoSW50ZXJ2YWwpKQoKamFjY190b19iYXNlbGluZSA8LSBsaXN0KAogIGFieF9qYWNjX3RvX2Jhc2VsaW5lICU+JSBtdXRhdGUoSW50ZXJ2YWwgPSBBYnhfSW50ZXJ2YWwsIFJlbERheSA9IEFieF9SZWxEYXkpICU+JQogICAgc2VsZWN0KE1lYXNfSUQsIFN1YmplY3QsIEdyb3VwLCBJbnRlcnZhbCwgUmVsRGF5LCBkaXN0X3RvX2Jhc2VsaW5lKSwKICBkaWV0X2phY2NfdG9fYmFzZWxpbmUgJT4lIG11dGF0ZShJbnRlcnZhbCA9IERpZXRfSW50ZXJ2YWwsIFJlbERheSA9IERpZXRfUmVsRGF5KSAlPiUKICAgIHNlbGVjdChNZWFzX0lELCBTdWJqZWN0LCBHcm91cCwgSW50ZXJ2YWwsIFJlbERheSwgZGlzdF90b19iYXNlbGluZSksCiAgY2NfamFjY190b19iYXNlbGluZSAlPiUgbXV0YXRlKEludGVydmFsID0gQ0NfSW50ZXJ2YWwsIFJlbERheSA9IENDX1JlbERheSkgJT4lCiAgICBzZWxlY3QoTWVhc19JRCwgU3ViamVjdCwgR3JvdXAsIEludGVydmFsLCBSZWxEYXksIGRpc3RfdG9fYmFzZWxpbmUpLAogIG5vSXR2X2phY2NfdG9fYmFzZWxpbmUgJT4lIG11dGF0ZShSZWxEYXkgPSBEYXlzRnJvbVN0YXJ0KSAlPiUKICAgIHNlbGVjdChNZWFzX0lELCBTdWJqZWN0LCBHcm91cCwgSW50ZXJ2YWwsIFJlbERheSwgZGlzdF90b19iYXNlbGluZSkKKQpuYW1lcyhqYWNjX3RvX2Jhc2VsaW5lKSA8LSBjKCJBYngiLCAiRGlldCIsICJDQyIsICJOb0ludHYiKQpqYWNjX3RvX2Jhc2VsaW5lIDwtIHBseXI6OmxkcGx5KGphY2NfdG9fYmFzZWxpbmUsIGZ1bmN0aW9uKGRmKSBkZiwgLmlkID0gInBlcnR1cmJhdGlvbiIpICU+JQogIG11dGF0ZShJbnRlcnZhbCA9IGZhY3RvcihJbnRlcnZhbCwgbGV2ZWxzID0gbmFtZXMoaW50dl9jb2xzKSkpCgpzYXZlKGxpc3QgPSBjKCJicmF5RC5paHMiLCAiYnJheS5kZiIsICJicmF5X3RvX2Jhc2VsaW5lIiwKICAgICAgICAgICAgICAiamFjY2FyZEQiLCAiamFjYy5kZiIsICJqYWNjX3RvX2Jhc2VsaW5lIiwKICAgICAgICAgICAgICAidW5pRnJhY0QubHN0IiwgInVuaUZyYWMuZGYiKSwKICAgICBmaWxlID0gIm91dHB1dC9wYWlyd2lzZV9kaXN0X3RvX2Jhc2VsaW5lX3N1YmpfMTZTLnJkYSIpCgpgYGAKCmBgYHtyIGphY2MtdG8tYmFzZWxpbmUsIGZpZy53aWR0aD04fQpqYWNjX3RvX2Jhc2VsaW5lICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gUmVsRGF5LCB5ID0gZGlzdF90b19iYXNlbGluZSwgCiAgICAgICAgZ3JvdXAgPSBTdWJqZWN0LCBjb2xvciA9IEludGVydmFsKSkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBTdWJqZWN0KSwgYWxwaGEgPSAwLjcsIGx3ZCA9IDAuNSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC41LCBzaXplID0gMS4yKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBpbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZmFjZXRfd3JhcCh+IHBlcnR1cmJhdGlvbiwgc2NhbGVzID0gImZyZWVfeCIpICsKICBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT0zKSkpICsKICB4bGFiKCJEYXlzIGZyb20gIHBlcnR1cmJhdGlvbiIpICsKICB5bGFiKCJKYWNjYXJkIGRpc3RhbmNlIHRvIGJhc2VsaW5lIikgCgpgYGAKCmBgYHtyIGphY2MtdG8tYmFzZWxpbmUtcGVydHVyYiwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9CmphY2NfdG9fYmFzZWxpbmUgJT4lCiAgZmlsdGVyKHBlcnR1cmJhdGlvbiAhPSAiTm9JbnR2IikgJT4lCiAgZ2dwbG90KAogICAgYWVzKHggPSBSZWxEYXksIHkgPSBkaXN0X3RvX2Jhc2VsaW5lLCAKICAgICAgICBncm91cCA9IFN1YmplY3QsIGNvbG9yID0gSW50ZXJ2YWwpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFN1YmplY3QpLCBhbHBoYSA9IDAuNywgbHdkID0gMC41KSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUsIHNpemUgPSAxKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBpbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZmFjZXRfd3JhcCh+IHBlcnR1cmJhdGlvbiwgc2NhbGVzID0gImZyZWVfeCIsIG5jb2wgPSAzKSArCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tICBwZXJ0dXJiYXRpb24iKSArCiAgeWxhYigiSmFjY2FyZCBkaXN0YW5jZSB0byBiYXNlbGluZSIpIAoKYGBgCgpgYGB7ciBqYWNjLXRvLWJhc2VsaW5lLXBlcnR1cmItem9vbSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9CmphY2NfdG9fYmFzZWxpbmUgJT4lCiAgZmlsdGVyKHBlcnR1cmJhdGlvbiAhPSAiTm9JbnR2IiwgUmVsRGF5IDw9MzAsIFJlbERheSA+PSAtMzApICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gUmVsRGF5LCB5ID0gZGlzdF90b19iYXNlbGluZSwgCiAgICAgICAgZ3JvdXAgPSBTdWJqZWN0LCBjb2xvciA9IEludGVydmFsKSkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBTdWJqZWN0KSwgYWxwaGEgPSAwLjcsIGx3ZCA9IDAuNSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC41LCBzaXplID0gMSkgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gaW50dl9jb2xzKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArIAogIGZhY2V0X3dyYXAofiBwZXJ0dXJiYXRpb24sIG5jb2wgPSAzKSArCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tICBwZXJ0dXJiYXRpb24iKSArCiAgeWxhYigiSmFjY2FyZCBkaXN0YW5jZSB0byBiYXNlbGluZSIpIAoKYGBgCgoKYGBge3IgYWJ4LWphY2MtdG8tYmFzZWxpbmUsIGZpZy53aWR0aD04fQphYnhfamFjY190b19iYXNlbGluZSAlPiUKICBtdXRhdGUoQWJ4X0ludGVydmFsID0gZmFjdG9yKEFieF9JbnRlcnZhbCwgbGV2ZWwgPSBuYW1lcyhhYnhfaW50dl9jb2xzKSkpICU+JQogIGZpbHRlcihBYnhfUmVsRGF5ID49IC01MCkgJT4lCiAgZ2dwbG90KAogICAgYWVzKHggPSBBYnhfUmVsRGF5LCB5ID0gZGlzdF90b19iYXNlbGluZSwgCiAgICAgICAgZ3JvdXAgPSBTdWJqZWN0LCBjb2xvciA9IEFieF9JbnRlcnZhbCkpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU3ViamVjdCksIGFscGhhID0gMC43LCBsd2QgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSwgc2l6ZSA9IDEuMikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYWJ4X2ludHZfY29scykgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKyAKICBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT0zKSkpICsKICB4bGFiKCJEYXlzIGZyb20gaW5pdGlhbCBhbnRpYmlvdGljIGRvc2UiKSArCiAgeWxhYigiSmFjY2FyZCBkaXN0YW5jZSB0byA3IHByZS1hbnRpYmlvdGljIHNhbXBsZXMiKQpgYGAKCgpgYGB7ciBhYngtamFjYy10by1iYXNlbGluZS16b29tLCBmaWcud2lkdGg9OH0KYWJ4X2phY2NfdG9fYmFzZWxpbmUgJT4lCiAgbXV0YXRlKEFieF9JbnRlcnZhbCA9IGZhY3RvcihBYnhfSW50ZXJ2YWwsIGxldmVsID0gbmFtZXMoYWJ4X2ludHZfY29scykpKSAlPiUKICBmaWx0ZXIoQWJ4X1JlbERheSA8PSAzMCwgQWJ4X1JlbERheSA+PSAtMzApICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gQWJ4X1JlbERheSwgeSA9IGRpc3RfdG9fYmFzZWxpbmUsIAogICAgICAgIGdyb3VwID0gU3ViamVjdCwgY29sb3IgPSBBYnhfSW50ZXJ2YWwpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFN1YmplY3QpLCBhbHBoYSA9IDAuNywgbHdkID0gMC41KSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUsIHNpemUgPSAxLjUpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGFieF9pbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tIGluaXRpYWwgYW50aWJpb3RpYyBkb3NlIikgKwogIHlsYWIoIkphY2NhcmQgZGlzdGFuY2UgdG8gNyBwcmUtYW50aWJpb3RpYyBzYW1wbGVzIikgKwogIHlsaW0oMC4xLCAxLjApCgpgYGAKCmBgYHtyIGRpZXQtamFjYy10by1iYXNlbGluZSwgZmlnLndpZHRoPTh9CgpkaWV0X2phY2NfdG9fYmFzZWxpbmUgJT4lCiAgbXV0YXRlKERpZXRfSW50ZXJ2YWwgPSBmYWN0b3IoRGlldF9JbnRlcnZhbCwgbGV2ZWwgPSBuYW1lcyhkaWV0X2ludHZfY29scykpKSAlPiUKICBmaWx0ZXIoRGlldF9SZWxEYXkgPD0gNTApICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gRGlldF9SZWxEYXksIHkgPSBkaXN0X3RvX2Jhc2VsaW5lLCAKICAgICAgICBncm91cCA9IFN1YmplY3QsIGNvbG9yID0gRGlldF9JbnRlcnZhbCkpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU3ViamVjdCksIGFscGhhID0gMC43LCBsd2QgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgc2l6ZSA9IDEuMikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gZGlldF9pbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tIGRpZXQgaW5pdGlhdGlvbiIpICsKICB5bGFiKCJKYWNjYXJkIGRpc3RhbmNlIHRvIDcgcHJlLWRpZXQgc2FtcGxlcyIpCgpgYGAKCgpgYGB7ciBkaWV0LWphY2MtdG8tYmFzZWxpbmUtem9vbSwgZmlnLndpZHRoPTh9CmRpZXRfamFjY190b19iYXNlbGluZSAlPiUKICBtdXRhdGUoRGlldF9JbnRlcnZhbCA9IGZhY3RvcihEaWV0X0ludGVydmFsLCBsZXZlbCA9IG5hbWVzKGRpZXRfaW50dl9jb2xzKSkpICU+JQogIGZpbHRlcihEaWV0X1JlbERheSA8PSAzMCwgRGlldF9SZWxEYXkgPj0gLTMwKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoeCA9IERpZXRfUmVsRGF5LCB5ID0gZGlzdF90b19iYXNlbGluZSwgCiAgICAgICAgZ3JvdXAgPSBTdWJqZWN0LCBjb2xvciA9IERpZXRfSW50ZXJ2YWwpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFN1YmplY3QpLCBhbHBoYSA9IDAuNywgbHdkID0gMC41KSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcsIHNpemUgPSAxLjIpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGRpZXRfaW50dl9jb2xzKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArIAogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTMpKSkgKwogIHhsYWIoIkRheXMgZnJvbSBkaWV0IGluaXRpYXRpb24iKSArCiAgeWxhYigiSmFjY2FyZCBkaXN0YW5jZSB0byA3IHByZS1kaWV0IHNhbXBsZXMiKSArCiAgeWxpbSgwLjEsIDEuMCkKCmBgYAoKYGBge3IgY2MtamFjYy10by1iYXNlbGluZSwgZmlnLndpZHRoPTh9CmNjX2phY2NfdG9fYmFzZWxpbmUgJT4lCiAgbXV0YXRlKENDX0ludGVydmFsID0gZmFjdG9yKENDX0ludGVydmFsLCBsZXZlbCA9IG5hbWVzKGNjX2ludHZfY29scykpKSAlPiUKICBmaWx0ZXIoQ0NfUmVsRGF5ID49IC01MCAsIENDX1JlbERheSA8PSA1MCkgJT4lCiAgZ2dwbG90KAogICAgYWVzKHggPSBDQ19SZWxEYXksIHkgPSBkaXN0X3RvX2Jhc2VsaW5lLCAKICAgICAgICBncm91cCA9IFN1YmplY3QsIGNvbG9yID0gQ0NfSW50ZXJ2YWwpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFN1YmplY3QpLCBhbHBoYSA9IDAuNywgbHdkID0gMC41KSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcsIHNpemUgPSAxLjIpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNjX2ludHZfY29scykgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKyAKICBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT0zKSkpICsKICB4bGFiKCJEYXlzIGZyb20gY29sb24gY2xlYW5vdXQiKSArCiAgeWxhYigiSmFjY2FyZCBkaXN0YW5jZSB0byA3IHByZS1jb2xvbi1jbGVhbm91dCBzYW1wbGVzIikKCmBgYAoKYGBge3IgY2MtamFjYy10by1iYXNlbGluZS16b29tLCBmaWcud2lkdGg9OH0KY2NfamFjY190b19iYXNlbGluZSAlPiUKICBtdXRhdGUoQ0NfSW50ZXJ2YWwgPSBmYWN0b3IoQ0NfSW50ZXJ2YWwsIGxldmVsID0gbmFtZXMoY2NfaW50dl9jb2xzKSkpICU+JQogZmlsdGVyKENDX1JlbERheSA+PSAtMzAgLCBDQ19SZWxEYXkgPD0gMzApICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gQ0NfUmVsRGF5LCB5ID0gZGlzdF90b19iYXNlbGluZSwgCiAgICAgICAgZ3JvdXAgPSBTdWJqZWN0LCBjb2xvciA9IENDX0ludGVydmFsKSkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBTdWJqZWN0KSwgYWxwaGEgPSAwLjcsIGx3ZCA9IDAuNSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC43LCBzaXplID0gMS4yKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjY19pbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tIGNvbG9uIGNsZWFub3V0IikgKwogIHlsYWIoIkphY2NhcmQgZGlzdGFuY2UgdG8gNyBwcmUtY29sb24tY2xlYW5vdXQgc2FtcGxlcyIpICsKICB5bGltKDAuMSwgMS4wKQoKYGBgCgoKIyMgKFVud2VpZ2h0ZWQpIFVuaUZyYWMKCgpgYGB7ciwgZXZhbCA9IEZBTFNFfQphYnhfdW5pRnJhY190b19iYXNlbGluZSA8LSB1bmlGcmFjLmRmICU+JQogIGZpbHRlcihBYnhfUmVsRGF5XzEgPj0gLTcgJiBBYnhfUmVsRGF5XzEgPD0gMCkgJT4lCiAgZ3JvdXBfYnkoU3ViamVjdCwgR3JvdXAsIEFieF9SZWxEYXlfMikgJT4lCiAgc3VtbWFyaXplKGRpc3RfdG9fYmFzZWxpbmUgPSBtZWFuKGRpc3QpKSAlPiUKICByZW5hbWUoQWJ4X1JlbERheSA9IEFieF9SZWxEYXlfMikgJT4lCiAgbGVmdF9qb2luKFNNUCkKCmRpZXRfdW5pRnJhY190b19iYXNlbGluZSA8LSB1bmlGcmFjLmRmICU+JQogIGZpbHRlcihEaWV0X1JlbERheV8xID49IC03ICYgRGlldF9SZWxEYXlfMSA8PSAwKSAlPiUKICBncm91cF9ieShTdWJqZWN0LCBHcm91cCwgRGlldF9SZWxEYXlfMikgJT4lCiAgc3VtbWFyaXplKGRpc3RfdG9fYmFzZWxpbmUgPSBtZWFuKGRpc3QpKSAlPiUKICByZW5hbWUoRGlldF9SZWxEYXkgPSBEaWV0X1JlbERheV8yKSAlPiUgCiAgbGVmdF9qb2luKFNNUCkKCmNjX3VuaUZyYWNfdG9fYmFzZWxpbmUgPC0gdW5pRnJhYy5kZiAlPiUKICBmaWx0ZXIoQ0NfUmVsRGF5XzEgPj0gLTcgJiBDQ19SZWxEYXlfMSA8PSAwKSAlPiUKICBncm91cF9ieShTdWJqZWN0LCBHcm91cCwgQ0NfUmVsRGF5XzIpICU+JQogIHN1bW1hcml6ZShkaXN0X3RvX2Jhc2VsaW5lID0gbWVhbihkaXN0KSkgJT4lCiAgcmVuYW1lKENDX1JlbERheSA9IENDX1JlbERheV8yKSAlPiUKICBsZWZ0X2pvaW4oU01QKQoKCm5vSXR2X3VuaUZyYWNfdG9fYmFzZWxpbmUgPC0gdW5pRnJhYy5kZiAlPiUKICBmaWx0ZXIoR3JvdXAgPT0gIk5vSW50diIsIERheXNGcm9tU3RhcnRfMSA+PSAwLCBEYXlzRnJvbVN0YXJ0XzEgPD0gMTApICU+JQogIGdyb3VwX2J5KFN1YmplY3QsIEdyb3VwLCBEYXlzRnJvbVN0YXJ0XzIpICU+JQogIHN1bW1hcml6ZShkaXN0X3RvX2Jhc2VsaW5lID0gbWVhbihkaXN0KSkgJT4lCiAgcmVuYW1lKERheXNGcm9tU3RhcnQgPSBEYXlzRnJvbVN0YXJ0XzIpICU+JQogIGxlZnRfam9pbihTTVApICU+JQogIG11dGF0ZShJbnRlcnZhbCA9IGFzLmNoYXJhY3RlcihJbnRlcnZhbCkpCgp1bmlGcmFjX3RvX2Jhc2VsaW5lIDwtIGxpc3QoCiAgYWJ4X3VuaUZyYWNfdG9fYmFzZWxpbmUgJT4lIG11dGF0ZShJbnRlcnZhbCA9IEFieF9JbnRlcnZhbCwgUmVsRGF5ID0gQWJ4X1JlbERheSkgJT4lCiAgICBzZWxlY3QoTWVhc19JRCwgU3ViamVjdCwgR3JvdXAsIEludGVydmFsLCBSZWxEYXksIGRpc3RfdG9fYmFzZWxpbmUpLAogIGRpZXRfdW5pRnJhY190b19iYXNlbGluZSAlPiUgbXV0YXRlKEludGVydmFsID0gRGlldF9JbnRlcnZhbCwgUmVsRGF5ID0gRGlldF9SZWxEYXkpICU+JQogICAgc2VsZWN0KE1lYXNfSUQsIFN1YmplY3QsIEdyb3VwLCBJbnRlcnZhbCwgUmVsRGF5LCBkaXN0X3RvX2Jhc2VsaW5lKSwKICBjY191bmlGcmFjX3RvX2Jhc2VsaW5lICU+JSBtdXRhdGUoSW50ZXJ2YWwgPSBDQ19JbnRlcnZhbCwgUmVsRGF5ID0gQ0NfUmVsRGF5KSAlPiUKICAgIHNlbGVjdChNZWFzX0lELCBTdWJqZWN0LCBHcm91cCwgSW50ZXJ2YWwsIFJlbERheSwgZGlzdF90b19iYXNlbGluZSksCiAgbm9JdHZfdW5pRnJhY190b19iYXNlbGluZSAlPiUgbXV0YXRlKFJlbERheSA9IERheXNGcm9tU3RhcnQpICU+JQogICAgc2VsZWN0KE1lYXNfSUQsIFN1YmplY3QsIEdyb3VwLCBJbnRlcnZhbCwgUmVsRGF5LCBkaXN0X3RvX2Jhc2VsaW5lKQopCm5hbWVzKHVuaUZyYWNfdG9fYmFzZWxpbmUpIDwtIGMoIkFieCIsICJEaWV0IiwgIkNDIiwgIk5vSW50diIpCnVuaUZyYWNfdG9fYmFzZWxpbmUgPC0gcGx5cjo6bGRwbHkodW5pRnJhY190b19iYXNlbGluZSwgZnVuY3Rpb24oZGYpIGRmLCAuaWQgPSAicGVydHVyYmF0aW9uIikgJT4lCiAgbXV0YXRlKEludGVydmFsID0gZmFjdG9yKEludGVydmFsLCBsZXZlbHMgPSBuYW1lcyhpbnR2X2NvbHMpKSkKCnNhdmUobGlzdCA9IGMoImJyYXlELmlocyIsICJicmF5LmRmIiwgImJyYXlfdG9fYmFzZWxpbmUiLAogICAgICAgICAgICAgICJqYWNjYXJkRCIsICJqYWNjLmRmIiwgImphY2NfdG9fYmFzZWxpbmUiLAogICAgICAgICAgICAgICJ1bmlGcmFjRC5sc3QiLCAidW5pRnJhYy5kZiIsICJ1bmlGcmFjX3RvX2Jhc2VsaW5lIiksCiAgICAgZmlsZSA9ICJvdXRwdXQvcGFpcndpc2VfZGlzdF90b19iYXNlbGluZV9zdWJqXzE2Uy5yZGEiKQoKYGBgCgpgYGB7ciB1bmlGcmFjLXRvLWJhc2VsaW5lLCBmaWcud2lkdGg9OH0KdW5pRnJhY190b19iYXNlbGluZSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoeCA9IFJlbERheSwgeSA9IGRpc3RfdG9fYmFzZWxpbmUsIAogICAgICAgIGdyb3VwID0gU3ViamVjdCwgY29sb3IgPSBJbnRlcnZhbCkpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU3ViamVjdCksIGFscGhhID0gMC43LCBsd2QgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSwgc2l6ZSA9IDEuMikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gaW50dl9jb2xzKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArIAogIGZhY2V0X3dyYXAofiBwZXJ0dXJiYXRpb24sIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tICBwZXJ0dXJiYXRpb24iKSArCiAgeWxhYigiVW5pRnJhYyBkaXN0YW5jZSB0byBiYXNlbGluZSIpIAoKYGBgCgpgYGB7ciB1bmlGcmFjLXRvLWJhc2VsaW5lLXBlcnR1cmIsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD00fQp1bmlGcmFjX3RvX2Jhc2VsaW5lICU+JQogIGZpbHRlcihwZXJ0dXJiYXRpb24gIT0gIk5vSW50diIpICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gUmVsRGF5LCB5ID0gZGlzdF90b19iYXNlbGluZSwgCiAgICAgICAgZ3JvdXAgPSBTdWJqZWN0LCBjb2xvciA9IEludGVydmFsKSkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBTdWJqZWN0KSwgYWxwaGEgPSAwLjcsIGx3ZCA9IDAuNSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC41LCBzaXplID0gMSkgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gaW50dl9jb2xzKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArIAogIGZhY2V0X3dyYXAofiBwZXJ0dXJiYXRpb24sIHNjYWxlcyA9ICJmcmVlX3giLCBuY29sID0gMykgKwogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTMpKSkgKwogIHhsYWIoIkRheXMgZnJvbSAgcGVydHVyYmF0aW9uIikgKwogIHlsYWIoIlVuaUZyYWMgZGlzdGFuY2UgdG8gYmFzZWxpbmUiKSAKCmBgYAoKYGBge3IgdW5pRnJhYy10by1iYXNlbGluZS1wZXJ0dXJiLXpvb20sIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD00fQp1bmlGcmFjX3RvX2Jhc2VsaW5lICU+JQogIGZpbHRlcihwZXJ0dXJiYXRpb24gIT0gIk5vSW50diIsIFJlbERheSA8PTMwLCBSZWxEYXkgPj0gLTMwKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoeCA9IFJlbERheSwgeSA9IGRpc3RfdG9fYmFzZWxpbmUsIAogICAgICAgIGdyb3VwID0gU3ViamVjdCwgY29sb3IgPSBJbnRlcnZhbCkpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU3ViamVjdCksIGFscGhhID0gMC43LCBsd2QgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSwgc2l6ZSA9IDEpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGludHZfY29scykgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKyAKICBmYWNldF93cmFwKH4gcGVydHVyYmF0aW9uLCBuY29sID0gMykgKwogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTMpKSkgKwogIHhsYWIoIkRheXMgZnJvbSAgcGVydHVyYmF0aW9uIikgKwogIHlsYWIoIlVuaUZyYWMgZGlzdGFuY2UgdG8gYmFzZWxpbmUiKSAKCmBgYAoKCmBgYHtyIGFieC11bmlGcmFjLXRvLWJhc2VsaW5lLCBmaWcud2lkdGg9OH0KYWJ4X3VuaUZyYWNfdG9fYmFzZWxpbmUgJT4lCiAgbXV0YXRlKEFieF9JbnRlcnZhbCA9IGZhY3RvcihBYnhfSW50ZXJ2YWwsIGxldmVsID0gbmFtZXMoYWJ4X2ludHZfY29scykpKSAlPiUKICBmaWx0ZXIoQWJ4X1JlbERheSA+PSAtNTApICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gQWJ4X1JlbERheSwgeSA9IGRpc3RfdG9fYmFzZWxpbmUsIAogICAgICAgIGdyb3VwID0gU3ViamVjdCwgY29sb3IgPSBBYnhfSW50ZXJ2YWwpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFN1YmplY3QpLCBhbHBoYSA9IDAuNywgbHdkID0gMC41KSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUsIHNpemUgPSAxLjIpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGFieF9pbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tIGluaXRpYWwgYW50aWJpb3RpYyBkb3NlIikgKwogIHlsYWIoIlVuaUZyYWMgZGlzdGFuY2UgdG8gNyBwcmUtYW50aWJpb3RpYyBzYW1wbGVzIikKYGBgCgoKYGBge3IgYWJ4LXVuaUZyYWMtdG8tYmFzZWxpbmUtem9vbSwgZmlnLndpZHRoPTh9CmFieF91bmlGcmFjX3RvX2Jhc2VsaW5lICU+JQogIG11dGF0ZShBYnhfSW50ZXJ2YWwgPSBmYWN0b3IoQWJ4X0ludGVydmFsLCBsZXZlbCA9IG5hbWVzKGFieF9pbnR2X2NvbHMpKSkgJT4lCiAgZmlsdGVyKEFieF9SZWxEYXkgPD0gMzAsIEFieF9SZWxEYXkgPj0gLTMwKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoeCA9IEFieF9SZWxEYXksIHkgPSBkaXN0X3RvX2Jhc2VsaW5lLCAKICAgICAgICBncm91cCA9IFN1YmplY3QsIGNvbG9yID0gQWJ4X0ludGVydmFsKSkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBTdWJqZWN0KSwgYWxwaGEgPSAwLjcsIGx3ZCA9IDAuNSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC41LCBzaXplID0gMS41KSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBhYnhfaW50dl9jb2xzKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArIAogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTMpKSkgKwogIHhsYWIoIkRheXMgZnJvbSBpbml0aWFsIGFudGliaW90aWMgZG9zZSIpICsKICB5bGFiKCJVbmlGcmFjIGRpc3RhbmNlIHRvIDcgcHJlLWFudGliaW90aWMgc2FtcGxlcyIpICsKICB5bGltKDAuMSwgMS4wKQoKYGBgCgpgYGB7ciBkaWV0LXVuaUZyYWMtdG8tYmFzZWxpbmUsIGZpZy53aWR0aD04fQoKZGlldF91bmlGcmFjX3RvX2Jhc2VsaW5lICU+JQogIG11dGF0ZShEaWV0X0ludGVydmFsID0gZmFjdG9yKERpZXRfSW50ZXJ2YWwsIGxldmVsID0gbmFtZXMoZGlldF9pbnR2X2NvbHMpKSkgJT4lCiAgZmlsdGVyKERpZXRfUmVsRGF5IDw9IDUwKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoeCA9IERpZXRfUmVsRGF5LCB5ID0gZGlzdF90b19iYXNlbGluZSwgCiAgICAgICAgZ3JvdXAgPSBTdWJqZWN0LCBjb2xvciA9IERpZXRfSW50ZXJ2YWwpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFN1YmplY3QpLCBhbHBoYSA9IDAuNywgbHdkID0gMC41KSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcsIHNpemUgPSAxLjIpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGRpZXRfaW50dl9jb2xzKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArIAogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTMpKSkgKwogIHhsYWIoIkRheXMgZnJvbSAgZGlldCBpbml0aWF0aW9uIikgKwogIHlsYWIoIlVuaUZyYWMgZGlzdGFuY2UgdG8gNyBwcmUtZGlldCBzYW1wbGVzIikKCmBgYAoKCmBgYHtyIGRpZXQtdW5pRnJhYy10by1iYXNlbGluZS16b29tLCBmaWcud2lkdGg9OH0KZGlldF91bmlGcmFjX3RvX2Jhc2VsaW5lICU+JQogIG11dGF0ZShEaWV0X0ludGVydmFsID0gZmFjdG9yKERpZXRfSW50ZXJ2YWwsIGxldmVsID0gbmFtZXMoZGlldF9pbnR2X2NvbHMpKSkgJT4lCiAgZmlsdGVyKERpZXRfUmVsRGF5IDw9IDMwLCBEaWV0X1JlbERheSA+PSAtMzApICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gRGlldF9SZWxEYXksIHkgPSBkaXN0X3RvX2Jhc2VsaW5lLCAKICAgICAgICBncm91cCA9IFN1YmplY3QsIGNvbG9yID0gRGlldF9JbnRlcnZhbCkpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU3ViamVjdCksIGFscGhhID0gMC43LCBsd2QgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgc2l6ZSA9IDEuMikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gZGlldF9pbnR2X2NvbHMpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKSArCiAgeGxhYigiRGF5cyBmcm9tIGRpZXQgaW5pdGlhdGlvbiIpICsKICB5bGFiKCJVbmlGcmFjIGRpc3RhbmNlIHRvIDcgcHJlLWRpZXQgc2FtcGxlcyIpICsKICB5bGltKDAuMSwgMS4wKQoKYGBgCgpgYGB7ciBjYy11bmlGcmFjLXRvLWJhc2VsaW5lLCBmaWcud2lkdGg9OH0KY2NfdW5pRnJhY190b19iYXNlbGluZSAlPiUKICBtdXRhdGUoQ0NfSW50ZXJ2YWwgPSBmYWN0b3IoQ0NfSW50ZXJ2YWwsIGxldmVsID0gbmFtZXMoY2NfaW50dl9jb2xzKSkpICU+JQogIGZpbHRlcihDQ19SZWxEYXkgPj0gLTUwICwgQ0NfUmVsRGF5IDw9IDUwKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoeCA9IENDX1JlbERheSwgeSA9IGRpc3RfdG9fYmFzZWxpbmUsIAogICAgICAgIGdyb3VwID0gU3ViamVjdCwgY29sb3IgPSBDQ19JbnRlcnZhbCkpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU3ViamVjdCksIGFscGhhID0gMC43LCBsd2QgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgc2l6ZSA9IDEuMikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY2NfaW50dl9jb2xzKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArIAogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTMpKSkgKwogIHhsYWIoIkRheXMgZnJvbSBjb2xvbiBjbGVhbm91dCIpICsKICB5bGFiKCJVbmlGcmFjIGRpc3RhbmNlIHRvIDcgcHJlLWNvbG9uLWNsZWFub3V0IHNhbXBsZXMiKQoKYGBgCgpgYGB7ciBjYy11bmlGcmFjLXRvLWJhc2VsaW5lLXpvb20sIGZpZy53aWR0aD04fQpjY191bmlGcmFjX3RvX2Jhc2VsaW5lICU+JQogIG11dGF0ZShDQ19JbnRlcnZhbCA9IGZhY3RvcihDQ19JbnRlcnZhbCwgbGV2ZWwgPSBuYW1lcyhjY19pbnR2X2NvbHMpKSkgJT4lCiBmaWx0ZXIoQ0NfUmVsRGF5ID49IC0zMCAsIENDX1JlbERheSA8PSAzMCkgJT4lCiAgZ2dwbG90KAogICAgYWVzKHggPSBDQ19SZWxEYXksIHkgPSBkaXN0X3RvX2Jhc2VsaW5lLCAKICAgICAgICBncm91cCA9IFN1YmplY3QsIGNvbG9yID0gQ0NfSW50ZXJ2YWwpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFN1YmplY3QpLCBhbHBoYSA9IDAuNywgbHdkID0gMC41KSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcsIHNpemUgPSAxLjIpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNjX2ludHZfY29scykgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKyAKICBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT0zKSkpICsKICB4bGFiKCJEYXlzIGZyb20gY29sb24gY2xlYW5vdXQiKSArCiAgeWxhYigiVW5pRnJhYyBkaXN0YW5jZSB0byA3IHByZS1jb2xvbi1jbGVhbm91dCBzYW1wbGVzIikgKwogIHlsaW0oMC4xLCAxLjApCgpgYGAKCgoKCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAoK